/**
 * Copyright (c) Software Institute of PKU
 * All rights reserved. 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */
package edu.pku.sei.modeler.uml.internal;

import java.util.ArrayList;
import java.util.List;

import edu.pku.sei.modeler.explorer.registry.TreeViewProviderRegistry;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.core.MetaDataType;
import edu.pku.sei.modeler.model.core.MetaModel;
import edu.pku.sei.modeler.model.core.MetaPackage;
import edu.pku.sei.modeler.model.structure.MetaDiagram;
import edu.pku.sei.modeler.model.uml.Kernel.PrimitiveType;
import edu.pku.sei.modeler.uml.modelHelper.ModelFactory;
import edu.pku.sei.modeler.uml.modelHelper.ModelPackage;
import edu.pku.sei.modeler.uml.view.UMLModelContentProvider;
import edu.pku.sei.modeler.uml.view.UMLModelLabelProvider;

/**
 * @generated
 * 
 */
class GeneratedModelRoot {
	protected UMLModel model;

	public GeneratedModelRoot() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.pku.modeler.internal.IProjectModelRoot#getAllInstances()
	 */
	public List getAllInstances() {
		List list = this.getDiagramInstances();
		// list.add(this.getModelInstances());
		return list;
	}

	public List getDiagramInstances() {
		List list = new ArrayList();
		// diagramRoot.getContentRecursive(list);
		return list;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.pku.modeler.internal.IProjectModelRoot#getInstancesOf(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	public List getInstancesOf(String typeName) {
		List list = getAllInstances();
		ArrayList result = new ArrayList();
		if (typeName.equals("Type")) {
			for (int i = 0; i < list.size(); i++) {
				if (list.get(i) instanceof MetaDataType) {
					result.add(list.get(i));
				}
			}
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see edu.pku.modeler.internal.IProjectModelRoot#initModel()
	 */
	public void initModel(String modelName) {
		ModelFactory factory = new ModelFactory();
		ModelPackage pkg = new ModelPackage();
		// create model
		model = (UMLModel) factory.createElement(ModelPackage.__METAMODEL__,
				false);
		// register the model to ModelRegistry
		ModelRegistry.getRegistry().registerModel(model, factory, pkg);
		// register the model to package
		factory.registerToPackage(model, ModelPackage.__METAMODEL__);
		MetaPackage defaultPackage = factory.createMetaPackage();
		defaultPackage.setName("default_package");
		defaultPackage.setModel(model);
		model.setName(modelName);
		model.getPackages().add(defaultPackage);
		// by default, the target modeling tool need not these primitive types
		initPrimitiveType(factory);
	}

	// /*
	protected void initPrimitiveType(ModelFactory factory) {
		PrimitiveType booleanType = factory.createPrimitiveType();
		PrimitiveType integerType = factory.createPrimitiveType();
		PrimitiveType floatType = factory.createPrimitiveType();
		PrimitiveType doubleType = factory.createPrimitiveType();
		PrimitiveType charType = factory.createPrimitiveType();
		PrimitiveType stringType = factory.createPrimitiveType();
		booleanType.setName("boolean");
		integerType.setName("int");
		floatType.setName("float");
		doubleType.setName("double");
		charType.setName("char");
		stringType.setName("String");

		booleanType.setModel(model);
		integerType.setModel(model);
		floatType.setModel(model);
		doubleType.setModel(model);
		charType.setModel(model);
		stringType.setModel(model);

		List packages = model.getPackages();
		if (packages.size() > 0) {
			MetaPackage defaultPackage = (MetaPackage) packages.get(0);
			defaultPackage.getOtherElements().add(booleanType);
			defaultPackage.getOtherElements().add(integerType);
			defaultPackage.getOtherElements().add(floatType);
			defaultPackage.getOtherElements().add(doubleType);
			defaultPackage.getOtherElements().add(charType);
			defaultPackage.getOtherElements().add(stringType);
		}
		model.registerType(booleanType);
		model.registerType(integerType);
		model.registerType(floatType);
		model.registerType(doubleType);
		model.registerType(charType);
		model.registerType(stringType);
	}

	// */
	/**
	 * @return Returns the modelName.
	 */
	public String getModelName() {
		return model.getName();
	}

	/**
	 * @param modelName
	 *            The modelName to set.
	 */
	public void setModelName(String modelName) {
		model.setName(modelName);
	}

	public void addToModel(Object modelEle, MetaDiagram diagram) {
		// MetaModelContentProvider provider =
		// (MetaModelContentProvider)treeViewer.getContentProvider();
		// Object parent = provider.getParent(diagram);
		// if(parent instanceof MetaPackage) {
		// MetaPackage p = (MetaPackage)parent;
		// if(modelEle instanceof MetaNamedElement) {
		// p.getNamedElements().add(modelEle);
		// }
		// else {
		// p.getOtherElements().add(modelEle);
		// }
		// model.registerType(modelEle);
		// }
		// if(modelEle instanceof MetaModelElement) {
		// ((MetaModelElement)modelEle).setModel(model);
		// ((MetaModelElement)modelEle).addPropertyChangeListener(provider.getModelListener());
		// }
		// treeViewer.refresh(parent);
	}

	// ???Editor?????????????treeViewer??????
	public void removeFromModel(Object modelEle, MetaDiagram diagram) {
		// MetaModelContentProvider provider =
		// (MetaModelContentProvider)treeViewer.getContentProvider();
		// Object parent = provider.getParent(diagram);
		// if(parent instanceof MetaPackage) {
		// MetaPackage p = (MetaPackage)parent;
		// if(modelEle instanceof MetaNamedElement) {
		// p.getNamedElements().remove(modelEle);
		// }
		// else {
		// p.getOtherElements().remove(modelEle);
		// }
		// }
		// treeViewer.refresh(parent);
	}

	// /**
	// * @return Returns the treeViewer.
	// */
	// public TreeViewer getTreeViewer() {
	// return treeViewer;
	// }
	// /**
	// * @param treeViewer The treeViewer to set.
	// */
	// public void setTreeViewer(TreeViewer treeViewer) {
	// this.treeViewer = treeViewer;
	// }

	@SuppressWarnings("unchecked")
	public boolean hasDiagram(Object diagram) {
		if (model == null)
			return false;
		List<MetaPackage> pkgs = model.getPackages();
		for (MetaPackage pkg : pkgs) {
			if (hasDiagram(pkg, diagram))
				return true;
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	private boolean hasDiagram(MetaPackage parent, Object diagram) {
		List<MetaDiagram> diags = parent.getDiagrams();
		for (MetaDiagram diag : diags) {
			if (diag == diagram)
				return true;
		}
		List<MetaPackage> pkgs = parent.getSubPackages();
		for (MetaPackage pkg : pkgs) {
			if (hasDiagram(pkg, diagram))
				return true;
		}
		return false;
	}

	/**
	 * @return Returns the model.
	 */
	public MetaModel getModel() {
		return model;
	}

	/**
	 * @param model
	 *            The model to set.
	 */
	public void setModel(UMLModel model) {
		this.model = model;
	}
}
